package com.rongxue.filter;

import com.rongxue.utils.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: 于振京
 * Date: 2017/9/27
 * Time: 17:36
 * To change this template use File | Settings | File Templates.
 */
public class SecurityFilter extends HttpServlet implements Filter{


    private static final long serialVersionUID = 4731865507572808910L;

    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityFilter.class);

    private String contextPath;

    private transient AntPathMatcher urlMatcher = new AntPathMatcher();

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        String requestURI = httpRequest.getRequestURI();
        requestURI = requestURI.substring(contextPath.length());
        if (!requestURI.startsWith("/")) {
            requestURI = "/" + requestURI;
        }
        //防止CSRF攻击
        ResourceBundle rb = ResourceBundle.getBundle("resource/rzzf");
        String allowOrigin = rb.getString("allowOrigin");
        List<String> allowOriginList = Arrays.asList(allowOrigin.split(","));
        String currentOrigin = httpRequest.getHeader("Referer");
        if (null != currentOrigin) {
            currentOrigin = currentOrigin.substring(0, currentOrigin.lastIndexOf("/"));
            if (allowOriginList.contains(currentOrigin)) {
                httpResponse.setHeader("Access-Control-Allow-Origin", currentOrigin);
            } else {
                LOGGER.debug("拒绝访问:{}", requestURI);
                writeError(httpRequest, httpResponse, "您没有权限访问 " + requestURI);
                return;
            }
        }


        // logger.debug("Filter 拦截:[{}] {}, Accept:{}", new String[] { httpRequest.getMethod(), requestURI,
        // httpRequest.getHeader("Accept") });

    }

    public void init(FilterConfig config) throws ServletException {
        this.contextPath = getContextPath(config.getServletContext());
    }

    private String getContextPath(ServletContext context) {
        String contextPath = context.getContextPath();

        if (contextPath == null || contextPath.length() == 0) {
            contextPath = "/";
        }

        return contextPath;
    }

    private void unauthorized(HttpServletRequest request, HttpServletResponse response) throws IOException,
            ServletException {
        if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
        } else {
            request.getRequestDispatcher("/login.do").forward(request, response);
        }
    }

    private void writeError(HttpServletRequest request, HttpServletResponse response, String message)
            throws IOException,
            ServletException {
        if (request.getHeader("accept").indexOf("application/json") > -1
                && "XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
            try {
                String contentType = "application/json";
                response.setContentType(contentType);
                response.setCharacterEncoding("UTF-8");
                Map<String, Object> jsonMap = new HashMap<String, Object>();
                jsonMap.put("result", 0);
                jsonMap.put("message", message);
                String json = JsonUtils.objectToJson(jsonMap);
                response.getWriter().print(json);
                response.getWriter().flush();
                response.getWriter().close();
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
        } else {
            request.setAttribute("exception", message);
            request.getRequestDispatcher("/error.jsp").forward(request, response);
        }
    }
}
